package parser.domain;

import java.util.Set;

public class Grammar {
	private Set<NonTerminalSymbol> nonTerminals;
	private Set<TerminalSymbol> terminals;
	private Set<Production> productionRules;
	private NonTerminalSymbol startingSymbol;

	Grammar(Set<NonTerminalSymbol> nonTerminals, Set<TerminalSymbol> terminals,
			Set<Production> productionRules, NonTerminalSymbol startingSymbol) {
		this.nonTerminals = nonTerminals;
		this.terminals = terminals;
		this.productionRules = productionRules;
		this.startingSymbol = startingSymbol;
	}

	/**
	 * Checks if the grammar is a regullar grammar.
	 * 
	 * @return
	 */
	public boolean isRegular() {
		boolean sInRhs = false;
		boolean sToEps = false;
		for (Production p : productionRules) {
			if (!(p.getLhs() instanceof NonTerminalSymbol)) {
				return false;
			}
			if (p.getRhs().size() > 2) {// if the p.getRhs() has more than 2
										// symbols
				// return false
				return false;
			}

			if (p.getRhs().size() == 2) {
				if (p.getRhs().get(1).equals(startingSymbol)) {
					sInRhs = true;
				}
				if (!(p.getRhs().get(0) instanceof TerminalSymbol)
						|| !(p.getRhs().get(1) instanceof NonTerminalSymbol)) {
					return false;
				}
			}

			if (p.getRhs().get(0) instanceof NonTerminalSymbol) {
				return false;// if the p.getRhs() contains only a nonterminal,
				// return false
			}

			if (p.getRhs().get(0).equals(new TerminalSymbol("eps"))
					&& !p.getLhs().equals(startingSymbol)) {
				return false; // return false if the anything else than the
				// starting symbol transforms in eps
			}

			if (p.getRhs().get(0).equals(new TerminalSymbol("eps"))) {
				sToEps = true;
			}

		}
		return !(sToEps && sInRhs);
	}

	public Set<NonTerminalSymbol> getNonTerminals() {
		return nonTerminals;
	}

	public Set<TerminalSymbol> getTerminals() {
		return terminals;
	}

	public Set<Production> getProductionRules() {
		return productionRules;
	}

	public NonTerminalSymbol getStartingSymbol() {
		return startingSymbol;
	}

	public String toString() {
		String res;
		res = "NonTerminals : " + getNonTerminals() + "\r\n";
		res += "Terminals : " + getTerminals() + "\r\n";
		res += "Starting symbol: " + getStartingSymbol() + "\r\n";
		res += "Productions: \r\n";
		for (Production p : getProductionRules()) {
			res += p + "\r\n";
		}
		return res;
	}

}
